package org.zhangkun.jmsg.ui.swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import org.zhangkun.jmsg.bean.DataPack;
import org.zhangkun.jmsg.bean.DataPackage;
import org.zhangkun.jmsg.bean.Msg;
import org.zhangkun.jmsg.bean.SendMsgInfo;
import org.zhangkun.jmsg.bean.User;
import org.zhangkun.jmsg.core.UserManager;
import org.zhangkun.jmsg.core.listener.RecvMsgListener;
import org.zhangkun.jmsg.core.listener.UserListener;
import org.zhangkun.jmsg.core.network.MsgTransport;
import org.zhangkun.jmsg.core.network.NetConnection;
import org.zhangkun.jmsg.core.network.filetransport.SendFiles;
import org.zhangkun.jmsg.ui.swing.listener.MsgViewListener;
import org.zhangkun.jmsg.ui.swing.view.MsgPanel;
import org.zhangkun.jmsg.ui.swing.view.SWTMsgView;
import org.zhangkun.jmsg.util.FileUtil;
import java.awt.Toolkit;

public class SendMsgDialog extends JFrame implements DropTargetListener,
		RecvMsgListener, UserListener, MsgViewListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5644328857255766569L;
	private JPanel buttonPane;
	private MsgPanel msgPanel;

	private JTextField sendsField;

	private SwingWorker<Void, Integer> sendsThread;
	private User user;
	private JButton okButton;
	private JButton sendsBtn;
	private JButton sendFileBtn;

	private boolean loadFinish = false;

	/**
	 * Create the dialog.
	 */
	public SendMsgDialog(User u) {
		setIconImage(u.getPhoto());
		this.user = u;
		setTitle("[" + user.getGroup() + "] " + user.getName());
		UserManager.addUserListener(this);
		// frm.getNetConnection().getResponseDataPackage().addReportListener(this);
		getContentPane().setLayout(new BorderLayout());

		// scrollPane.setViewportView(inputMsg);

		msgPanel = new SWTMsgView(this);
		getContentPane().add(msgPanel, BorderLayout.CENTER);

		buttonPane = new JPanel();
		getContentPane().add(buttonPane, BorderLayout.SOUTH);
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
		sendsField = new JTextField("10");
		sendsField.setDocument(new PlainDocument() {
			/**
			 * 
			 */
			private static final long serialVersionUID = 8780228624539741773L;

			public void insertString(int offs, String str, AttributeSet a)
					throws BadLocationException {
				// 若字符串为空，直接返回。
				if (str == null) {
					return;
				}
				if (!str.matches("\\d+"))
					return;
				super.insertString(offs, str, a);// 把字符添加到文本框
			}
		});
		buttonPane.add(sendsField);
		sendsField.setColumns(5);
		sendFileBtn = new JButton("发送文件");
		sendFileBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new SendFileDialog(SendMsgDialog.this.user);
			}
		});
		sendsBtn = new JButton("轰炸");
		sendsBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (sendsThread != null) {
					sendsThread.cancel(true);
					sendsBtn.setText("轰炸");
					return;
				}
				final String sendsMsg = msgPanel.getInputMsg();
				if (sendsMsg.length() != 0) {
					okButton.setEnabled(false);
					msgPanel.setInputMsg("");
					sendsBtn.setText("停止");
					msgPanel.appendSendMsg(sendsMsg);
					sendsThread = new SwingWorker<Void, Integer>() {
						private int l = 0;
						private int num = Integer.parseInt(sendsField.getText());

						@Override
						protected Void doInBackground() throws Exception {
							// TODO Auto-generated method stub
							String ip = SendMsgDialog.this.user.getIp();
							for (int i = 0; i < num && !isCancelled(); i++) {
								NetConnection.instance.sendNoRevertMsg(ip,
										sendsMsg);
								publish(l);
								l++;
							}
							return null;
						}

						@Override
						public void done() {
							sendsBtn.setText("轰炸");
							msgPanel.appendSendMsg("已成功轰炸" + l + "条！");
							sendsField.setText("" + num);
							okButton.setEnabled(true);
							sendsThread = null;
						}

						protected void process(List<Integer> pairs) {
							int i = (Integer) pairs.get(pairs.size() - 1);
							sendsField.setText("" + i);
						}
					};
					sendsThread.execute();
				} else
					JOptionPane.showMessageDialog(SendMsgDialog.this,
							"没有输入任何内容！");

			}
		});
		buttonPane.add(sendsBtn);

		JButton button = new JButton("资料");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(
						SendMsgDialog.this,
						"昵称：" + user.getName() + "\n主机：" + user.getHostName()
								+ "\nIP：" + user.getIp() + "\n分组："
								+ user.getGroup());
			}
		});
		buttonPane.add(button);
		buttonPane.add(sendFileBtn);

		okButton = new JButton("发送");
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				sendMsg();
			}
		});

		JButton cancelButton = new JButton("关闭");
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				close();
			}
		});
		cancelButton.setActionCommand("关闭");
		buttonPane.add(cancelButton);
		okButton.setActionCommand("发送");
		buttonPane.add(okButton);
		getRootPane().setDefaultButton(okButton);

		new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
		setSize(0, 0);
		setVisible(true);

		addWindowListener(new WindowAdapter() {

			@Override
			public void windowOpened(WindowEvent e) {
				// TODO Auto-generated method stub\
			}

			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				close();
			}

		});

	}

	public void close() {
		MainWindow.instance.closeSendDialog(SendMsgDialog.this);
		UserManager.removeUserListener(SendMsgDialog.this);
		SendMsgDialog.this.dispose();
	}

	@Override
	public void acceptRecvMsg(SendMsgInfo sendMsgInfo, boolean result) {
		// TODO Auto-generated method stub
		if (!result) {
			if (sendMsgInfo.getOtherData() == null) {
				String systemMsg = "您发送的消息：<div style=\"filter:Gray;border:1px solid gray;width:99%;overflow:auto; \">"
						+ sendMsgInfo.getDp().getMsg()
						+ "</div>对方没有接收，可能是对方已经下线！<a href=\"javascript:editor.setInput(this.previousSibling.innerHTML)\">重新发送</a>";
				if (!this.isVisible()) {
					MainWindow.instance.addMsg(user, new Msg(systemMsg,
							Msg.MSG_SYSTEM));
					dispose();
				} else {
					msgPanel.appendSystemMsg(systemMsg);
				}
			}
		}
		if (sendMsgInfo.getOtherData() instanceof SendFiles) {
			if (!result) {
				String systemMsg = "您向对方发送的文件对方未接收到!";
				if (!this.isVisible()) {
					MainWindow.instance.addMsg(user, new Msg(systemMsg,
							Msg.MSG_SYSTEM));
					dispose();
				} else {
					msgPanel.appendSystemMsg(systemMsg);
				}
			} else {
				SendFiles sf = (SendFiles) sendMsgInfo.getOtherData();
				sf.startUp();
			}
		}
	}

	@Override
	public void addUser(User u) {
		// TODO Auto-generated method stub
		if (u.equals(this.user))
			this.userLoading();
	}

	@Override
	public void delAllUser() {
		// TODO Auto-generated method stub
		msgPanel.appendSystemMsg("列表已刷新！请等待用户上线。");
		// okButton.setEnabled(false);
		// sendsField.setEnabled(false);
		// sendFileBtn.setEnabled(false);
		// sendsBtn.setEnabled(false);
	}

	@Override
	public void dragEnter(DropTargetDragEvent dtde) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dragExit(DropTargetEvent dte) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dragOver(DropTargetDragEvent dtde) {
		// TODO Auto-generated method stub

	}

	@Override
	public void drop(DropTargetDropEvent dtde) {
		// TODO Auto-generated method stub
		new SendFileDialog(user).drop(dtde);
	}

	@Override
	public void dropActionChanged(DropTargetDragEvent dtde) {
		// TODO Auto-generated method stub

	}

	public User getUser() {
		return user;
	}

	@Override
	public void modifyUser(User u) {
		// TODO Auto-generated method stub
	}

	@Override
	public void removeUser(User u) {
		// TODO Auto-generated method stub
		if (u.equals(this.user))
			this.userExit();
	}

	public void userExit() {
		// TODO Auto-generated method stub
		msgPanel.appendSystemMsg("对方已经下线！");
		// okButton.setEnabled(false);
		// sendsField.setEnabled(false);
		// sendFileBtn.setEnabled(false);
		// sendsBtn.setEnabled(false);
		// buttonPane.setVisible(false);
	}

	public void userLoading() {
		// TODO Auto-generated method stub
		msgPanel.appendSystemMsg("对方已经上线！");
		// okButton.setEnabled(true);
		// sendsField.setEnabled(true);
		// sendFileBtn.setEnabled(true);
		// sendsBtn.setEnabled(true);
		// buttonPane.setVisible(true);

	}

	public void addMsg(Msg msg) {
		// TODO Auto-generated method stub
		if (msg.getType() == Msg.MSG_RECEIVE)
			msgPanel.appendReceiveMsg(user, msg.getMsg());
		else if (msg.getType() == Msg.MSG_SEND)
			msgPanel.appendSendMsg(msg.getMsg());
		else if (msg.getType() == Msg.MSG_SYSTEM)
			msgPanel.appendSystemMsg(msg.getMsg());
		else if (msg.getType() == Msg.MSG_SHAKE) {
			msgPanel.appendSystemMsg("对方向您发送了一个窗口抖动。");
			shakeWindow();
		} else if (msg.getType() == Msg.MSG_START_INPUT) {
			setTitle("[" + user.getGroup() + "] " + user.getName() + " 正在输入");
		} else if (msg.getType() == Msg.MSG_END_INPUT) {
			setTitle("[" + user.getGroup() + "] " + user.getName());
		}
	}

	@Override
	public void onSendMsgEvent() {
		// TODO Auto-generated method stub
		sendMsg();
	}

	private void sendMsg(String msg) {
		DataPack dp = new DataPack();
		dp.setDataType(DataPackage.IPMSG_SENDMSG
				| DataPackage.IPMSG_SENDCHECKOPT);
		dp.setMsg(msg);
		dp.setSendToHostAddres(SendMsgDialog.this.user.getIp());
		SendMsgInfo m = new SendMsgInfo(dp, SendMsgDialog.this, true);
		MsgTransport.instance.addMsg(m);
		msgPanel.appendSendMsg(msg);
	}

	public void sendMsg() {
		String msg = msgPanel.getInputMsg();
		if (msg.length() == 0) {
			JOptionPane.showMessageDialog(SendMsgDialog.this, "没有输入任何内容！");
			return;
		}
		String inMsg = msgPanel.getInputMsg();
		sendMsg(inMsg);
		msgPanel.setInputMsg("");
	}

	private Thread shakeThread;

	private void shakeWindow() {
		if (shakeThread == null || !shakeThread.isAlive()) {
			shakeThread = new Thread() {
				public void run() {
					if (!isFocused()) {
						requestFocusInWindow();
					}
					Point pos = getLocation();
					int x = pos.x, y = pos.y, loop = 1;
					int d = 1;
					for (int i = 20; i >= 0; i--) {
						if (d == 1)
							x = pos.x + loop;
						if (d == 2)
							y = pos.y - loop;
						if (d == 3)
							x = pos.x - loop;
						if (d == 4)
							y = pos.y + loop;
						d++;
						if (d > 4) {
							d = 1;
						}
						if (loop > 7) {
							loop = 3;
						} else
							loop++;
						setLocation(x, y);
						try {
							Thread.sleep(30);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					setLocation(pos);
				}
			};
			shakeThread.start();
		}
	}

	@Override
	public void onSendWindowShake() {
		// TODO Auto-generated method stub
		shakeWindow();
		DataPack dp = new DataPack();
		dp.setDataType(DataPackage.IPMSG_SENDSHAKE
				| DataPackage.IPMSG_SENDCHECKOPT);
		dp.setSendToHostAddres(SendMsgDialog.this.user.getIp());
		SendMsgInfo smi = new SendMsgInfo(dp, this, true);
		MsgTransport.instance.addMsg(smi);
		msgPanel.appendSystemMsg("您发送了一个窗口抖动。");
	}

	@Override
	public void onStartInput() {
		// TODO Auto-generated method stub
		DataPack dp = new DataPack();
		dp.setDataType(DataPackage.IPMSG_SEND_STARTINPUT);
		dp.setSendToHostAddres(SendMsgDialog.this.user.getIp());
		NetConnection.instance.sendBroadcast(dp);
	}

	@Override
	public void onEndInput() {
		// TODO Auto-generated method stub
		DataPack dp = new DataPack();
		dp.setDataType(DataPackage.IPMSG_SEND_ENDINPUT);
		dp.setSendToHostAddres(SendMsgDialog.this.user.getIp());
		NetConnection.instance.sendBroadcast(dp);
	}

	@Override
	public void onSendJMsgApplicationEvent(String msg) {
		// TODO Auto-generated method stub
		SendFiles sf = new SendFiles();
		sf.setUser(user);
		File file = FileUtil.getJarFile();
		sf.appendPath(file.getAbsolutePath(), file.length());
		DataPack dp = new DataPack();
		dp.setDataType(DataPackage.IPMSG_SENDMSG
				| DataPackage.IPMSG_SENDCHECKOPT
				| DataPackage.IPMSG_FILEATTACHOPT);
		dp.setMsg(sf.getMsg());
		dp.setSendToHostAddres(user.getIp());
		SendMsgInfo smi = new SendMsgInfo(dp, this, true);
		smi.setOtherData(sf);
		MsgTransport.instance.addMsg(smi);
		sf.setPackageID(dp.getDataID());
		if (msg != null)
			sendMsg(msg);
	}

	@Override
	public void onLoadFinish() {
		setVisible(false);
		setSize(480, 500);
		setMinimumSize(new Dimension(530, 400));
		this.setLocationRelativeTo(null);
		setVisible(true);
		// new Thread() {
		// public void run() {
		if (user.getVersion() == User.CLIENT_JMSG) {
			msgPanel.setUseHTML(true);
		} else {
			msgPanel.setUseHTML(false);
		}
		// }
		// }.start();
		loadFinish = true;
	}

	public void setLoadFinish(boolean loadFinish) {
		this.loadFinish = loadFinish;
	}

	public boolean isLoadFinish() {
		return loadFinish;
	}
}
